package com.ssy.lingxi.pay.utils;

import cn.hutool.core.date.DateUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisUtils;
import com.ssy.lingxi.pay.api.model.vo.request.CreditBillInitVO;
import com.ssy.lingxi.pay.service.ICreditBillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 定时器
 * @author 伍将
 * @date 2020/11/25
 * @version 2.0.0
 */
@Component
@EnableScheduling
@EnableAsync
public class Scheduler {

    private static final Logger logger = LoggerFactory.getLogger(Scheduler.class);

    @Resource
    private ICreditBillService billService;

    @Resource
    private IRedisUtils redisUtils;

    /**
     * 定时任务
     * 每天1:30执行
     */
    @Async
    @Scheduled(cron = "0 30 01 ? * *")
    public void ScheduledTask() {

        String key = Constants.REDIS_KEY_PAY_TASK;
        // 检查定时服务是否正在执行，如正在执行则退出任务
        Object obj = redisUtils.get(key, Constants.REDIS_PAY_INDEX);
        if (obj != null) {
            Boolean isExecute = (Boolean) obj;
            if (isExecute) {
                logger.info("定时任务正在执行...");
                return;
            }
        }
        // 设置定时任务正在执行
        redisUtils.set(key, true, Constants.REDIS_PAY_INDEX);

        try {
            // 初始化逾期账单
            CreditBillInitVO initVO = new CreditBillInitVO();
            // 逾期时间为前一天
            initVO.setInitDate(DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -1), "yyyy-MM-dd 23:59:59"));
            Wrapper wrapper = billService.initOverdue(initVO);
            if (wrapper == null || wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                logger.info("初始化授信逾期账单定时任务失败");
            }
            logger.info("处理授信逾期账单");
        } catch (Exception e) {
            logger.info("初始化授信逾期账单定时任务失败：{}", e.getMessage());
        }
        try {
            // 初始化新账单
            CreditBillInitVO initVO = new CreditBillInitVO();
            initVO.setInitDate(DateUtil.format(DateUtil.date(), "yyyy-MM-dd"));
            Wrapper wrapper = billService.init(initVO);
            if (wrapper == null || wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                logger.info("初始化授信账单定时任务失败");
            }
            logger.info("处理授信账单");
        } catch (Exception e) {
            logger.info("初始化授信账单定时任务失败：{}", e.getMessage());
        }
        try {
            // 已出账单通知
            String time = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
            Wrapper wrapper = billService.billNotice(time);
            if (wrapper == null || wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                logger.info("授信已出账单通知任务失败");
            }
            logger.info("授信已出账单通知任务");
        } catch (Exception e) {
            logger.info("授信已出账单通知任务失败：{}", e.getMessage());
        }
        try {
            // 逾期一天后发通知
            String time = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -1), "yyyy-MM-dd 23:59:59");
            Wrapper wrapper = billService.overdueNotice(time);
            if (wrapper == null || wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                logger.info("授信逾期账单通知任务失败");
            }
            logger.info("授信逾期账单通知任务");
        } catch (Exception e) {
            logger.info("授信逾期账单通知任务失败：{}", e.getMessage());
        }
        try {
            // 账单前三天发通知
            String time = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 3), "yyyy-MM-dd 23:59:59");
            Wrapper wrapper = billService.repayNotice(time);
            if (wrapper == null || wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                logger.info("授信账单还款通知任务失败");
            }
            logger.info("授信账单还款通知任务");
        } catch (Exception e) {
            logger.info("授信账单还款通知任务失败：{}", e.getMessage());
        }

        // 设置定时任务非执行状态
        redisUtils.set(key, false, Constants.REDIS_PAY_INDEX);
    }
}
